package com.project.frame.common.exception;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.project.frame.common.model.BaseResp;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.UnauthenticatedException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Priority;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * desc
 *
 * @author lw007
 * @date 2021/12/22
 */
@Slf4j
@Priority(1)
@RestControllerAdvice
public class GlobalExceptionHandler {

    @Value("${page.error404:/home/404}")
    private String error404;
    @Value("${page.noauth:/user/login}")
    private String unauthorizedUrl;


    @ExceptionHandler(Exception.class)
    public ModelAndView handleException(Exception e,HttpServletRequest request, HttpServletResponse response) {
        if(isAjaxOrSwagger(request,response)){
            BaseResp resp = new BaseResp(BaseResp.RC_NOT,e.getMessage());
            writeJson(response,resp);
            return null;
        }else {
            ModelAndView mv = new ModelAndView(error404);
            mv.addObject("message", "页面跳转前的处理出现异常了");
            return mv;
        }
    }

    @ExceptionHandler(UnauthenticatedException.class)
    public ModelAndView handleUnauthorizedException(UnauthenticatedException e,HttpServletRequest request, HttpServletResponse response) {
        if(isAjaxOrSwagger(request,response)){
            BaseResp resp = new BaseResp(BaseResp.AUTH_NOT,e.getMessage());
            writeJson(response,resp);
            return null;
        }else {
            ModelAndView mv = new ModelAndView(unauthorizedUrl);
            return mv;
        }
    }


    private boolean isAjaxOrSwagger(HttpServletRequest request, HttpServletResponse response){
        String referer = request.getHeader("Referer");
        String ajaxHeader = request.getHeader("X-Requested-With");// ajax请求特有的请求头
        String contentType = request.getHeader("Content-Type");//application/json请求也返回true

        String refererType = request.getHeader("Referer-Type");
        if("ui".equals(refererType)) {	//如果是前后端分离, 在Header中新增关键字
            return true;
        }
        if("XMLHttpRequest".equals(ajaxHeader)){
            return true;
        }
        if(StrUtil.isNotEmpty(referer) && referer.contains("swagger-ui.html")){
            return true;
        }
        if(StrUtil.isBlank(contentType)){
            return false;
        }
        if(contentType.contains("json")){
            return true;
        }
        if(contentType.contains("form-data")){
            return true;
        }
        return false;
    }

    protected void writeJson(HttpServletResponse response, BaseResp resp){
        try {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
            response.getWriter().write(JSON.toJSONString(resp));
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}
